package com.hs.egova.controller;

import com.hs.egova.mapping.User;
import com.hs.egova.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 文件上传
 * @author husheng
 * @version v1.0
 * @date 2021/7/20 9:21
 * @email husheng@egova.com.cn
 */
@RestController
@Slf4j
@Api(tags = "文件上传下载")
public class FileController {

    @ApiOperation("文件上传")
    @PostMapping("/upload")
    public String upload(@RequestPart("file")MultipartFile file) {
        //文件信息
        log.info("file name: {}", file.getOriginalFilename());
        log.info("file size: {}", file.getSize());
        //下面是保存本地

        InputStream in = null;
        try {
            Path target = Paths.get("./" + file.getOriginalFilename());
            in = file.getInputStream();;
            Files.copy(in, target);
        }catch (IOException e){
            log.error("save file error", e);
            return "false";
        }finally {
            //最后关闭文件流
            if (in != null) {
                try {
                    in.close();
                }catch (IOException e) {
                    log.warn("close inputstream error", e);
                }
            }
        }
        return "OK";
    }

    @ApiOperation("文件上传2")
    @PostMapping("/upload2")
    public String upload(User user, @RequestPart(value = "file", required = false)MultipartFile file) {
        //文件信息
        log.info("file name: {}", file.getOriginalFilename());
        log.info("file size: {}", file.getSize());
        //下面是保存本地
        log.info("user {}", user.toString());
        InputStream in = null;
        try {
            Path target = Paths.get("./" + file.getOriginalFilename());
            in = file.getInputStream();;
            Files.copy(in, target);
        }catch (IOException e){
            log.error("save file error", e);
            return "false";
        }finally {
            //最后关闭文件流
            if (in != null) {
                try {
                    in.close();
                }catch (IOException e) {
                    log.warn("close inputstream error", e);
                }
            }
        }
        return "OK";
    }

    @ApiOperation("文件上传3")
    @PostMapping("/upload3")
    public String upload(UserVo userVo) {
        MultipartFile file = userVo.getFile();
        //文件信息
        log.info("file name: {}", file.getOriginalFilename());
        log.info("file size: {}", file.getSize());
        //下面是保存本地
        log.info("user {}", userVo.toString());
        InputStream in = null;
        try {
            Path target = Paths.get("./" + file.getOriginalFilename());
            in = file.getInputStream();;
            Files.copy(in, target);
        }catch (IOException e){
            log.error("save file error", e);
            return "false";
        }finally {
            //最后关闭文件流
            if (in != null) {
                try {
                    in.close();
                }catch (IOException e) {
                    log.warn("close inputstream error", e);
                }
            }
        }
        return "OK";
    }

    /**
     * 下载文件,文件较小时
     * @return
     */
    @ApiOperation("文件下载")
    @GetMapping("/download")
    public ResponseEntity<?> download() {
        //获取文件
        Path source = Paths.get("./README.md");
        try {
            String name = source.toFile().getName();
            byte[] bytes = Files.readAllBytes(source);
            HttpHeaders headers = new HttpHeaders();
            log.info("name :{}", name);
            headers.add("Content-Disposition", "attachment;filename=" + name);
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        }catch (IOException e) {
            log.error("read file error", e);
            return ResponseEntity.ok("false");
        }
    }

    /**
     * 大文件下载
     * @param response
     * @param fileName
     * @return
     */
    @ApiOperation("文件下载2")
    @GetMapping("/v2/download")
    public String fileDownload(HttpServletResponse response, @RequestParam("fileName") String fileName) throws UnsupportedEncodingException {
        String downloadPath = "D:\\Download";
        File file = new File(downloadPath+"/"+fileName);
        if(!file.exists()) {
            return "下载文件不存在";
        }
        response.reset();
        /**
         * 未知应用程序文件，会像设置HTTP头，Content-Disposition值为attachment的文件一样
         */
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setContentLength((int) file.length());
        /**
         * 设置content-disposition响应头控制浏览器以下载的形式打开文件
         * 中文文件件名使用URLEncoder.encode进行编码，防止乱码
         */
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        //try打开文件两种方式，免显示声明关闭
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));) {
            byte[] buff = new byte[1024];
            OutputStream os = response.getOutputStream();
            int i = 0;
            while ((i = bis.read(buff)) != -1) {
                os.write(buff, 0, i);
                os.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            log.error("{}", e);
            return "下载失败";
        }
        return "下载成功";
    }
}
